#include "command.h"
#include "metaFile.h"
// 线程维护一个当前客户端的访问路径 int pathId
int my_cd (MYSQL *mysql,char* path,int *pathId,char *result){
    if(!mysql){
        printf("数据库未连接!\n");
        return -1;
    }
    //  执行把传入path与filepath进行组合的操作得到一个newpath
    char new_path[ARRLEN] = {0};
    if(getFormattedPath(mysql, path, new_path, *pathId, NULL) != 0){
        return -1;
    }
    printf("new_path = %s\n",new_path);
    //  根据pathId获取当前用户名
    char cur_user[ARRLEN];
    if(getUsernameByFid(mysql, *pathId, cur_user) != 0){
        return -1;
    }
    //  检查这个newpath是否存在于文件元数据表格，
    //  若存在，则把pathId更改，若不存在，则返回cd错误  
    if(checkDirPathExists(mysql, new_path, cur_user) != 0){
        sprintf(result, "路径不存在!");
        return -1;
    } 
    //  如果走到这一步，那么当前目录就是新的pathId对应的new_path
    if(getFidByFilepath(mysql, new_path, cur_user, pathId) != 0){
        return -1;
    }
    strcpy(result, new_path);


    return 0;
}


//  输出目标路径下面的所有子目录和文件
//  先拼接绝对路径，获取这条路径对应的fid，
//  查询所有parent_id为此fid的条目，把所有条目的文件名或者目录名写入result
int my_ls(MYSQL *mysql,char* path,int pathId,char* result){
    if(!mysql){
        printf("数据库未连接!\n");
        return -1;
    }
    //  获取到ls想要操作的目录
    char new_path[ARRLEN] = {0};
    if(getFormattedPath(mysql, path, new_path, pathId, NULL) != 0){
        return -1;
    }
    //  根据pathId获取当前用户名
    char cur_user[ARRLEN];
    if(getUsernameByFid(mysql, pathId, cur_user) != 0){
        return -1;
    }
    printf("new_path = %s\n", new_path);
    //  检查new_path是否存在
    if(checkDirPathExists(mysql, new_path, cur_user) != 0){
        sprintf(result, "路径不存在!");
        return -1;
    }
    //  这是我暂时存储new_path对应的fid，我需要通过路径获取到
    int tempId = 0;
    if(getFidByFilepath(mysql, new_path, cur_user, &tempId) != 0){
        return -1;
    }

    //  查表所有parent_id为tempId的文件或子目录把自己的名字存入result
    char *query = (char *)malloc(QUERYLEN);
    snprintf(query, QUERYLEN, "SELECT fileName FROM fileMetaDataTable WHERE parentId='%d' AND userName='%s'",
            tempId, cur_user);
    if(mysql_query(mysql, query) != 0){
        printf("SQL 错误: %s\n", mysql_error(mysql));
        return -1;
    }
    printf("执行的 SQL: %s\n", query);
    MYSQL_RES *res = mysql_store_result(mysql);
    if(res == NULL){
        printf("查询结果为空!\n");
        sprintf(result, "路径错误!");
        return -1;
    }
    MYSQL_ROW row;
    result[0] = '\0';
    strcat(result,".\t..\t");
    while((row = mysql_fetch_row(res)) != NULL){
        strcat(result, row[0]);
        strcat(result, "\t");
    }
    mysql_free_result(res);
    free(query);
    return 0;
}

//  返回当前路径，把路径写入到result  
int my_pwd(MYSQL *mysql,int pathId,char* result){
    if(!mysql){
        printf("数据库未连接!\n");
        return -1;
    }
    //  使用根据fid获取路径能查表直接获取fid对应的路径
    if(getPathByFid(mysql, pathId, result) != 0){
        return -1;
    }
    return 0;
}

//  获取绝对路径，删除文件，
//  若有多个用户引用了这个文件，则在表中删除对应项，
//  若只有一个用户引用这个文件，则物理上删除文件
int removeFile(MYSQL *mysql,char* path,int pathId,char *result,char *phyPath){
    if(!mysql){
        printf("数据库未连接!\n");
        return -1;
    }
    //  获取目标文件所在路径
    char new_path[ARRLEN] = {0};
    char desName[ARRLEN] = {0};
    if(getFormattedPath(mysql, path, new_path, pathId, desName) != 0){
        return -1;
    }
    //  根据pathId获取当前用户名
    char cur_user[ARRLEN];
    if(getUsernameByFid(mysql, pathId, cur_user) != 0){
        return -1;
    }
    printf("new_path = %s\n",new_path);
    //  检查文件路径是否存在
    if(checkFilePathExists(mysql, new_path, cur_user) != 0){
        sprintf(result, "路径不存在!");
        return -1;
    }

    //  目的是找到当前用户下有没有这个文件
    //  如果有，再去检查所有用户下面有几个，大于一删除此用户对应目录项，等于一删除目录项并且物理删除文件
    //  如果没有则返回该用户没有这个文件
    char *query = (char *)malloc(QUERYLEN);
    snprintf(query, QUERYLEN, "SELECT hashName FROM fileMetaDataTable WHERE fileName='%s' AND userName='%s'",
             desName, cur_user);
    if(mysql_query(mysql, query) != 0){
        printf("SQL 错误: %s\n", mysql_error(mysql));
        return -1;
    } 
    printf("执行的 SQL: %s\n", query);
    MYSQL_RES *res = mysql_store_result(mysql);
    if(res == NULL){
        printf("查询结果为空\n");
        return -1;
    }
    MYSQL_ROW row = mysql_fetch_row(res);
    if(row == NULL){
        printf("未找到匹配记录!\n");
        mysql_free_result(res);
        return -1;
    }
    char hashname[ARRLEN] = {0};
    strcpy(hashname, row[0]);
    printf("hashname = %s\n", hashname);
    mysql_free_result(res);
    free(query);
    //  计算所有用户下面有多少hashName的目录项
    char *query2 = (char *)malloc(QUERYLEN);
    snprintf(query2, QUERYLEN, "SELECT COUNT(*) FROM fileMetaDataTable WHERE hashName='%s'",
            hashname);
    if(mysql_query(mysql, query2) != 0){
        printf("SQL 错误: %s\n", mysql_error(mysql));
        return -1;
    }
    printf("执行的 SQL: %s\n", query2);
    MYSQL_RES *res2 = mysql_store_result(mysql);
    if(res2 == NULL){
        printf("查询结果为空!\n");
        return -1;
    }
    MYSQL_ROW row2 = mysql_fetch_row(res2);
    if(row2 == NULL){
        printf("未找到匹配记录!\n");
        mysql_free_result(res2);
        return -1;
    }
    int count = atoi(row2[0]);
    mysql_free_result(res2); 
    free(query2);
    //  如果count大于等于一，则执行删除该文件在这个用户下的该条目录项  
    if(count >= 1){
        //  真实删除hashname文件
        if(count == 1){
            //  还需要拼接得到真正的物理地址！！！
            char rmFile_path[ARRLEN];
            strcpy(rmFile_path, phyPath);
            strcat(rmFile_path, hashname);
            printf("rmFile_path = %s\n", rmFile_path);
            remove(rmFile_path);
        }
        char *query3 = (char *)malloc(QUERYLEN);
        snprintf(query3, QUERYLEN, "DELETE FROM fileMetaDataTable WHERE filePath='%s' AND userName='%s'",
                new_path, cur_user);
        if(mysql_query(mysql, query3) != 0){
            printf("SQL 错误: %s\n", mysql_error(mysql));
            return -1;

        }
        printf("执行的 SQL: %s\n", query3);
        free(query3);
    }else{
        sprintf(result, "要删除的文件不存在于系统内!");
        printf("要删除的文件不存在于系统内!\n");
        return -1;
    }
    printf("删除文件成功!\n");
    sprintf(result, "删除文件成功!");
    return 0;
}
//  删除空目录
int removeDir(MYSQL *mysql,char* path,int pathId,char *result){
    if(!mysql){
        printf("数据库未连接!\n");
        return -1;
    }
    //  获取要删除的目录的路径
    char new_path[ARRLEN] = {0};
    if(getFormattedPath(mysql, path, new_path, pathId, NULL) != 0){
        return -1;
    }
    //  根据pathId获取当前用户名
    char cur_user[ARRLEN];
    if(getUsernameByFid(mysql, pathId, cur_user) != 0){
        return -1;
    }
    printf("new_path = %s\n", new_path);
    //  检查这个目录是否存在
    if(checkDirPathExists(mysql, new_path, cur_user) != 0){
        sprintf(result, "目录不存在!");
        return -1;
    }

    //  检查这个目录是否为空目录
    int tempId = 0;
    if(getFidByFilepath(mysql, new_path, cur_user, &tempId) != 0){
        return -1;
    }
    char *query = (char *)malloc(QUERYLEN);
    snprintf(query, QUERYLEN, "SELECT COUNT(parentId) FROM fileMetaDataTable WHERE parentId=%d AND userName='%s'",
            tempId, cur_user);
    if(mysql_query(mysql, query) != 0){
        printf("SQL 错误: %s\n", mysql_error(mysql));
        return -1;
    }
    printf("执行的 SQL: %s\n", query);
    MYSQL_RES *res = mysql_store_result(mysql);
    if(res == NULL){
        printf("查询结果为空!\n");
        return -1;
    }
    MYSQL_ROW row = mysql_fetch_row(res);
    if(row == NULL){
        printf("未找到匹配记录!\n");
        mysql_free_result(res);
        return -1;
    }

    int count = atoi(row[0]);
    mysql_free_result(res);
    free(query);
    if(count != 0){
        printf("目录非空，不允许删除!\n");
        sprintf(result, "目录非空，不允许删除!");
        return -1;
    }

    //  此时目录为空目录
    char *query2 = (char *)malloc(QUERYLEN);
    snprintf(query2, QUERYLEN, "DELETE FROM fileMetaDataTable WHERE filePath='%s' AND userName='%s'",
            new_path, cur_user);
    if(mysql_query(mysql, query2) != 0){
        printf("SQL 错误: %s\n", mysql_error(mysql));
        return -1;
    }
    printf("执行的 SQL: %s\n", query2);
    printf("删除目录成功!\n");
    sprintf(result, "删除目录成功!");
    free(query2);
    return 0;
}

//  创建新目录
int my_mkdir(MYSQL *mysql,char* path,int pathId,char *result){
    if(!mysql){
        printf("数据库未连接!\n");
        return -1;
    }

    //  获取想要建立目录的路径
    char new_path[ARRLEN] = {0};
    char dirName[ARRLEN] = {0};
    if(getFormattedPath(mysql, path, new_path, pathId, dirName) != 0){
        return -1;
    }
    //  根据pathId获取当前用户名
    char cur_user[ARRLEN];
    if(getUsernameByFid(mysql, pathId, cur_user) != 0){
        return -1;
    }
    //  检查是否目录已存在
    if(checkDirPathExists(mysql, new_path, cur_user) == 0){
        printf("目录已存在，新建目录失败!\n");
        sprintf(result, "目录已存在，新建目录失败!");
        return -1;
    }
    //  获取当前目录的父目录
    char *pre = NULL;
    char temp_path[ARRLEN] = {0};
    strcpy(temp_path, new_path);
    char *p = temp_path;
    while(*p != '\0'){
        if(*p == '/'){
            pre = p;
        }
        p++;
    }
    if(pre && pre != temp_path){
        *pre = '\0';
    }else{
        *(temp_path+1) = '\0';
    }
    char pre_path[ARRLEN] = {0};
    strcpy(pre_path, temp_path);
    //  根据父目录查询parent_id
    int p_id = -1;
    if(getFidByFilepath(mysql, pre_path, cur_user, &p_id) != 0){
        return -1;
    }
    char *query = (char *)malloc(QUERYLEN);
    snprintf(query, QUERYLEN, "INSERT INTO fileMetaDataTable (fileName,userName,parentId,fileType,filePath) "
            "VALUES ('%s','%s',%d,'d','%s')",dirName,cur_user, p_id, new_path);
    if(mysql_query(mysql, query) != 0){
        printf("SQL 错误: %s\n", mysql_error(mysql));
        return -1;
    }
    printf("执行的 SQL: %s\n", query);
    printf("创建目录成功!\n");
    sprintf(result, "创建目录成功!");
    free(query);
    return 0;
}
// 将上传的文件元数据添加到表中，如果同路径有同名文件，则在新文件名后面加(1)
int my_puts(MYSQL *mysql,char* path,int pathId,char* hashName){
    // path 格式化，并取得文件名
    char rightPath[ARRLEN]={0};
    char fileName[FILENAME_MAX]={0};
    if(getFormattedPath(mysql,path,rightPath,pathId,fileName)!=0){
        printf("command/my_puts: get right path error!\n");
        return -1;
    }
    
    //  根据pathId获取当前用户名
    char cur_user[ARRLEN];
    if(getUsernameByFid(mysql, pathId, cur_user) != 0){
        return -1;
    }
    // 文件存在，改名
    if(checkFilePathExists(mysql, rightPath,cur_user)==0){
        strncat(fileName,"(1)",4);
    }
    // 插表前准备
    fileMeta_t fileMeta;
    bzero(&fileMeta,sizeof(fileMeta_t));

    //  获取当前目录的父目录
    char *pre = NULL;
    char temp_path[ARRLEN] = {0};
    strcpy(temp_path, rightPath);
    char *p = temp_path;
    while(*p != '\0'){
        if(*p == '/'){
            pre = p;
        }
        p++;
    }
    if(pre && pre != temp_path){
        *pre = '\0';
    }else{
        *(temp_path+1) = '\0';
    }
    char pre_path[ARRLEN] = {0};
    strcpy(pre_path, temp_path);
    //  根据父目录查询parent_id
    int p_id = -1;
    if(getFidByFilepath(mysql, pre_path, cur_user, &p_id) != 0){
        return -1;
    }

    // insert data into table
    strcpy(fileMeta.fileName,fileName);
    strcpy(fileMeta.userName,cur_user);
    fileMeta.parentId = p_id;
    strcpy(fileMeta.hashName,hashName);
    fileMeta.fileType = 'f';
    strcpy(fileMeta.filePath,rightPath);
    
    if(insertDataToFileTable(mysql, &fileMeta)!=0){
         printf("command.c/puts: insert error!\n");
         return -1;
    }

    printf("puts:fname|%s|,uname|%s|,pId|%d|,hname|%s|,ftype|%c|,fpath|%s|\n",
           fileMeta.fileName,fileMeta.userName,fileMeta.parentId,
           fileMeta.hashName,fileMeta.fileType,fileMeta.filePath);
    return 0;
}
//  gets若存在，则返回文件物理路径，若不存在，则返回空
int my_gets(MYSQL *mysql,char *path,int pathId,char* absPath,char *phyPath){
    //  获取绝对路径
    char new_path[ARRLEN] = {0};
    char fileName[ARRLEN] = {0};
    if(getFormattedPath(mysql, path, new_path, pathId, fileName) != 0){
        return -1;
    }
    //  根据pathId获取当前用户名
    char cur_user[ARRLEN];
    if(getUsernameByFid(mysql, pathId, cur_user) != 0){
        return -1;
    }
    //  检查文件是否存在
    if(checkFilePathExists(mysql, new_path, cur_user) != 0){
        printf("文件不存在，获取失败!\n");
        return -1;
    }

    //  获取该文件的hashName
    char *query = (char *)malloc(QUERYLEN);
    snprintf(query, QUERYLEN,
             "SELECT hashName FROM fileMetaDataTable WHERE fileName = '%s' AND userName = '%s'",
             fileName, cur_user);
    if(mysql_query(mysql, query) != 0){
        printf("SQL 错误: %s\n", mysql_error(mysql));
        return -1;
    }
    printf("执行的 SQL: %s\n", query);
    MYSQL_RES *res = mysql_store_result(mysql);
    if(res == NULL){
        printf("查询结果为空!\n");
        return -1;
    }
    MYSQL_ROW row = mysql_fetch_row(res);
    if(row == NULL){
        printf("未找到匹配记录!\n");
        mysql_free_result(res);
        return -1;
    }
    char hashName[ARRLEN] = {0};
    strcpy(hashName, row[0]);

    //  返回物理地址
    strcpy(absPath, phyPath);
    strcat(absPath, hashName);
    
    return 0;
}


/* int main(int argc, char *argv[]){ */

    /* char res[ARRLEN]; */
    /* int pathId = 11; */
    //  cd测试
    /* char path[] = "/games/shot"; */
    /* my_cd(path,&pathId); */
    /* printf("pathId = %d\n", pathId); */
    //  ls测试
    /* char path[] = ""; */
    /* my_ls(path, pathId, res); */
    /* printf("res = %s\n", res); */

    //  pwd测试
    /* printf("%d\n", pathId); */
    /* my_pwd(pathId, res); */
    /* printf("res = %s\n", res); */

    //  rmdir测试
    /* char path[] = "cf"; */
    /* removeDir(path, pathId); */
    /* printf("pathId = %d\n",pathId); */

    //  mkdir测试
    /* char path[] = "cf"; */
    /* my_mkdir(path, pathId); */
    /* printf("pathId = %d", pathId); */

    //  rmFile测试
    /* char path[] = "/books/oversea/三国演义"; */
    /* removeFile(path, pathId); */

    //  puts测试
    /* int pathId = 11; */
    /* char path[] = "红与黑"; */
    /* char hashName[] = "dtuatjnnanaekw;kajkral"; */
    /* my_puts(path, pathId, hashName); */
    /* return 0; */

    //  gets测试
    /* int pathId = 11; */
    /* char *path = "红与黑"; */
    /* char *absPath; */
    /* my_gets(path, pathId, absPath); */
    /* printf("absPath = %s\n",absPath); */
    /* return 0; */
/* } */
